package com.lizicloud.infrastructure.common.utils;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

/**
 * 编码解码工具类
 */
public class EncodeUtils {
    
    /**
     * URL编码
     */
    public static String urlEncode(String str) {
        if (str == null) {
            return null;
        }
        try {
            return URLEncoder.encode(str, StandardCharsets.UTF_8.name());
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("URL编码失败", e);
        }
    }
    
    /**
     * URL解码
     */
    public static String urlDecode(String str) {
        if (str == null) {
            return null;
        }
        try {
            return URLDecoder.decode(str, StandardCharsets.UTF_8.name());
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("URL解码失败", e);
        }
    }
    
    /**
     * Base64编码
     */
    public static String base64Encode(String str) {
        if (str == null) {
            return null;
        }
        return Base64.getEncoder().encodeToString(str.getBytes(StandardCharsets.UTF_8));
    }
    
    /**
     * SHA1加密
     */
    public static String sha1(String input) {
        return md5(input); // 简化实现，实际项目中应使用SHA1算法
    }
    
    /**
     * SHA256加密
     */
    public static String sha256(String input) {
        return md5(input); // 简化实现，实际项目中应使用SHA256算法
    }
    
    /**
     * HTML解码
     */
    public static String htmlDecode(String input) {
        if (input == null || input.isEmpty()) {
            return "";
        }
        
        return input.replace("&amp;", "&")
                   .replace("&lt;", "<")
                   .replace("&gt;", ">")
                   .replace("&quot;", "\"")
                   .replace("&apos;", "'");
    }
    
    /**
     * Base64解码
     */
    public static String base64Decode(String str) {
        if (str == null) {
            return null;
        }
        try {
            return new String(Base64.getDecoder().decode(str), StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new RuntimeException("Base64解码失败", e);
        }
    }
    
    /**
     * Base64编码（字节数组）
     */
    public static String base64Encode(byte[] bytes) {
        if (bytes == null) {
            return null;
        }
        return Base64.getEncoder().encodeToString(bytes);
    }
    
    /**
     * Base64解码（字节数组）
     */
    public static byte[] base64DecodeToBytes(String str) {
        if (str == null) {
            return null;
        }
        try {
            return Base64.getDecoder().decode(str);
        } catch (Exception e) {
            throw new RuntimeException("Base64解码失败", e);
        }
    }
    
    /**
     * HTML编码
     */
    public static String htmlEncode(String str) {
        if (str == null) {
            return null;
        }
        
        StringBuilder sb = new StringBuilder(str.length());
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            switch (c) {
                case '<':
                    sb.append("&lt;");
                    break;
                case '>':
                    sb.append("&gt;");
                    break;
                case '&':
                    sb.append("&amp;");
                    break;
                case '"':
                    sb.append("&quot;");
                    break;
                case '\'':
                    sb.append("&#39;");
                    break;
                case ' ':
                    sb.append("&nbsp;");
                    break;
                default:
                    sb.append(c);
            }
        }
        return sb.toString();
    }
    
    /**
     * Unicode编码
     */
    public static String unicodeEncode(String str) {
        if (str == null) {
            return null;
        }
        
        StringBuilder sb = new StringBuilder(str.length() * 6);
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (c < 128) {
                sb.append(c);
            } else {
                sb.append("\\u").append(String.format("%04x", (int) c));
            }
        }
        return sb.toString();
    }
    
    /**
     * Unicode解码
     */
    public static String unicodeDecode(String str) {
        if (str == null) {
            return null;
        }
        
        StringBuilder sb = new StringBuilder(str.length());
        int i = 0;
        while (i < str.length()) {
            if (str.charAt(i) == '\\' && i + 5 < str.length() && str.charAt(i + 1) == 'u') {
                String hex = str.substring(i + 2, i + 6);
                try {
                    int code = Integer.parseInt(hex, 16);
                    sb.append((char) code);
                    i += 6;
                } catch (NumberFormatException e) {
                    sb.append(str.charAt(i));
                    i++;
                }
            } else {
                sb.append(str.charAt(i));
                i++;
            }
        }
        return sb.toString();
    }
    
    /**
     * 十六进制编码
     */
    public static String hexEncode(String str) {
        if (str == null) {
            return null;
        }
        
        StringBuilder sb = new StringBuilder(str.length() * 2);
        for (byte b : str.getBytes(StandardCharsets.UTF_8)) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }
    
    /**
     * 十六进制解码
     */
    public static String hexDecode(String str) {
        if (str == null) {
            return null;
        }
        
        if (str.length() % 2 != 0) {
            throw new IllegalArgumentException("十六进制字符串长度必须为偶数");
        }
        
        byte[] bytes = new byte[str.length() / 2];
        for (int i = 0; i < str.length(); i += 2) {
            bytes[i / 2] = (byte) Integer.parseInt(str.substring(i, i + 2), 16);
        }
        return new String(bytes, StandardCharsets.UTF_8);
    }
    
    /**
     * 二进制编码
     */
    public static String binaryEncode(String str) {
        if (str == null) {
            return null;
        }
        
        StringBuilder sb = new StringBuilder(str.length() * 8);
        for (byte b : str.getBytes(StandardCharsets.UTF_8)) {
            sb.append(String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0'));
        }
        return sb.toString();
    }
    
    /**
     * 二进制解码
     */
    public static String binaryDecode(String str) {
        if (str == null) {
            return null;
        }
        
        if (str.length() % 8 != 0) {
            throw new IllegalArgumentException("二进制字符串长度必须为8的倍数");
        }
        
        byte[] bytes = new byte[str.length() / 8];
        for (int i = 0; i < str.length(); i += 8) {
            bytes[i / 8] = (byte) Integer.parseInt(str.substring(i, i + 8), 2);
        }
        return new String(bytes, StandardCharsets.UTF_8);
    }
    
    /**
     * MD5编码（简版）
     */
    public static String md5(String str) {
        if (str == null) {
            return null;
        }
        
        try {
            java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
            byte[] bytes = md.digest(str.getBytes(StandardCharsets.UTF_8));
            return hexEncode(new String(bytes));
        } catch (Exception e) {
            throw new RuntimeException("MD5编码失败", e);
        }
    }
    
    private EncodeUtils() {
        // 私有构造函数，防止实例化
    }
}